package com.youlu.campus.starter.trace.filter;

import com.youlu.campus.starter.trace.bean.MDCParam;
import com.youlu.campus.starter.trace.config.TraceProperties;
import com.youlu.campus.starter.trace.consts.TraceConstants;
import com.youlu.campus.starter.trace.utils.MDCUtil;
import com.youlu.campus.starter.trace.utils.TraceIdUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@Slf4j
public class HttpTraceIdFilter implements Filter {

    public HttpTraceIdFilter() {
        log.info("HttpTraceIdFilter---------create ok");
    }

    private TraceProperties traceProperties;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //tomcat 容器启动 springboot 项目 关于servlet 的配置都会失效
        //filter 也是servlet 也是
        if (traceProperties == null) {
            WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext());
            traceProperties = applicationContext.getBean(TraceProperties.class);
        }
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        //先清除本地缓存
        try {
            MDCUtil.clear();
            MDCParam param = new MDCParam();
            String authorization = httpRequest.getHeader(TraceConstants.TOKEN_ID_KEY);
            String traceId = httpRequest.getHeader(TraceConstants.TRACE_ID_KEY);
            String upServer = httpRequest.getHeader(TraceConstants.UP_SERVER);
            if (StringUtils.isNotBlank(authorization)) {
                param.setAuthorization(authorization);
            }
            if (StringUtils.isBlank(traceId)) {
                traceId = TraceIdUtil.getTraceId();
            }
            param.setTraceId(traceId);
            if (StringUtils.isNotBlank(upServer)) {
                param.setUpServer(upServer);
            }
            param.setServerName(traceProperties.getServerName());
            MDCUtil.put(param);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            chain.doFilter(request, response);
        } finally {
            MDCUtil.clear();
        }
    }

}
